import { Button, Result } from "antd";
import { useMemo } from "react";
import { useLocation, useNavigate } from "react-router-dom";
import { ExceptionEnum } from "@/enums/exceptionEnum";
import { PageEnum } from "@/enums/pageEnum";

interface MapValue {
	title: string;
	subTitle: string;
	btnText?: string;
	icon?: string;
	handler?: Fn;
	status?: string;
}

interface PageProps {
	status?: number;
	title?: string;
	subTitle?: string;
	full?: boolean;
}

const Exception = (props: PageProps) => {
	// fix React18 "defaultProps" problem
	props = Object.assign({}, { status: ExceptionEnum.PAGE_NOT_FOUND, title: "", subTitle: "", full: false, ...props });

	const { state } = useLocation();
	const navigate = useNavigate();

	const statusMapRef = new Map<string | number, MapValue>();

	const prefixCls = "app-exception-page";

	statusMapRef.set(ExceptionEnum.PAGE_NOT_ACCESS, {
		title: "403",
		status: `${ExceptionEnum.PAGE_NOT_ACCESS}`,
		subTitle: "Sorry, you are not authorized to access this page.",
		btnText: "Back Home",
		handler: () => (props.full ? navigate(PageEnum.BASE_LOGIN) : navigate(PageEnum.BASE_HOME))
	});

	statusMapRef.set(ExceptionEnum.PAGE_NOT_FOUND, {
		title: "404",
		status: `${ExceptionEnum.PAGE_NOT_FOUND}`,
		subTitle: "Sorry, the page you visited does not exist.",
		btnText: "Back Home",
		handler: () => (props.full ? navigate(PageEnum.BASE_LOGIN) : navigate(PageEnum.BASE_HOME))
	});

	statusMapRef.set(ExceptionEnum.ERROR, {
		title: "500",
		status: `${ExceptionEnum.ERROR}`,
		subTitle: "Sorry, something went wrong.",
		btnText: "Back Home",
		handler: () => navigate(PageEnum.BASE_HOME)
	});

	/** Memo */

	const getStatus = useMemo(() => {
		return state ? +state?.status : +props.status;
	}, [props.status]);

	const getMapValue = useMemo((): MapValue => {
		return statusMapRef.get(getStatus) as MapValue;
	}, [getStatus]);

	return (
		<Result
			className={prefixCls}
			{...getMapValue}
			extra={
				getMapValue.btnText && (
					<Button type="primary" onClick={getMapValue.handler}>
						{getMapValue.btnText}
					</Button>
				)
			}
		/>
	);
};

export default Exception;
